import pandas as pd
import json
import re
from pathlib import Path


def extract_building_info_from_text(text):
    """从建筑描述文本中提取关键信息"""
    if pd.isna(text) or not isinstance(text, str):
        return {}

    result = {}

    # 提取建筑年代/时间信息
    year_patterns = [
        r'(\d{3,4})\s*年',
        r'建于(\d{3,4})',
        r'创建于(\d{3,4})',
        r'始建于(\d{3,4})',
        r'金大定(\d+)年',
        r'明昌(\d+)年',
        r'贞观(\d+)年',
        r'永乐(\d+)年',
        r'乾隆(\d+)年',
        r'康熙(\d+)年',
        r'光绪(\d+)年',
        r'唐太宗(?:贞观)?(\d+)年',
        r'隋(?:文帝)?(?:仁寿)?(\d+)年',
    ]

    # 提取尺寸信息
    size_patterns = [
        r'高\s*(\d+(?:\.\d+)?)\s*米',
        r'长\s*(\d+(?:\.\d+)?)\s*米',
        r'宽\s*(\d+(?:\.\d+)?)\s*米',
        r'直径\s*(\d+(?:\.\d+)?)\s*米',
        r'周回\s*(\d+(?:\.\d+)?)\s*里',
        r'面积\s*(\d+(?:\.\d+)?)\s*(?:万\s*)?平方米',
        r'占地\s*(\d+(?:\.\d+)?)\s*(?:万\s*)?平方米',
        r'总面积\s*(\d+(?:\.\d+)?)\s*(?:万\s*)?亩',
        r'(\d+(?:\.\d+)?)\s*亩',
    ]

    # 提取建筑类型（从描述中推断）
    building_types = {
        '寺庙': ['寺', '庙', '庵', '禅院', '佛寺', '道观'],
        '苑囿': ['园', '苑', '囿', '离宫', '行宫', '御园', '园林'],
        '桥梁': ['桥', '梁', '渡'],
        '水利': ['堰', '渠', '闸', '坝', '水利'],
        '宫殿': ['殿', '宫', '阁', '楼', '堂'],
        '陵墓': ['陵', '墓', '冢'],
        '其他': ['台', '坛', '城', '门']
    }

    # 提取建筑功能/用途
    function_patterns = [
        r'祭祀', r'朝会', r'居住', r'防御', r'交通',
        r'灌溉', r'游乐', r'宗教', r'政治', r'军事'
    ]

    # 提取建筑状态
    status_patterns = [
        r'毁于', r'焚毁', r'破坏', r'重修', r'重建',
        r'修复', r'保存', r'现存', r'遗址', r'废墟'
    ]

    # 提取年份
    for pattern in year_patterns:
        match = re.search(pattern, text)
        if match:
            try:
                year = match.group(1)
                # 处理年号转公元
                if pattern.startswith('金大定'):
                    result['built_year'] = 1161 + int(year) - 1
                elif pattern.startswith('明昌'):
                    result['built_year'] = 1190 + int(year) - 1
                elif pattern.startswith('贞观'):
                    result['built_year'] = 627 + int(year) - 1
                elif pattern.startswith('永乐'):
                    result['built_year'] = 1403 + int(year) - 1
                elif pattern.startswith('乾隆'):
                    result['built_year'] = 1736 + int(year) - 1
                elif pattern.startswith('康熙'):
                    result['built_year'] = 1662 + int(year) - 1
                elif pattern.startswith('光绪'):
                    result['built_year'] = 1875 + int(year) - 1
                elif pattern.startswith('唐太宗'):
                    result['built_year'] = 627 + int(year) - 1
                elif pattern.startswith('隋'):
                    result['built_year'] = 581 + int(year) - 1
                else:
                    year_num = int(year)
                    if 100 < year_num < 3000:
                        result['built_year'] = year_num
                break
            except:
                pass

    # 提取尺寸信息
    for pattern in size_patterns:
        match = re.search(pattern, text)
        if match:
            try:
                size_value = float(match.group(1))
                if '亩' in pattern:
                    result['area_mu'] = size_value  # 保留亩单位
                    result['area_sqkm'] = round(size_value / 1500, 4)  # 转换为平方公里
                elif '平方米' in pattern:
                    if '万' in match.group(0):
                        result['area_sqkm'] = size_value * 10  # 万平方米 = 0.1平方公里
                    else:
                        result['area_sqkm'] = size_value / 1000000  # 平方米转平方公里
                elif '里' in pattern:
                    result['perimeter_li'] = size_value  # 周回里数
                else:
                    # 线性尺寸
                    if '高' in pattern:
                        result['height_m'] = size_value
                    elif '长' in pattern:
                        result['length_m'] = size_value
                    elif '宽' in pattern:
                        result['width_m'] = size_value
                    elif '直径' in pattern:
                        result['diameter_m'] = size_value
                break
            except:
                pass

    # 推断建筑类型
    detected_types = []
    for btype, keywords in building_types.items():
        for keyword in keywords:
            if keyword in text:
                detected_types.append(btype)
                break

    if detected_types:
        result['inferred_types'] = list(set(detected_types))  # 去重

    # 提取功能
    functions = []
    for pattern in function_patterns:
        if re.search(pattern, text):
            functions.append(pattern)
    if functions:
        result['functions'] = functions

    # 提取状态信息
    for pattern in status_patterns:
        if re.search(pattern, text):
            result['status_note'] = pattern
            break

    return result


def extract_architectural_data_from_excel(file_path, sheet_name='总重点建筑'):
    """从Excel文件中提取建筑数据"""
    try:
        # 读取Excel文件
        df = pd.read_excel(file_path, sheet_name=sheet_name)

        # 打印列名用于调试
        print("Excel列名:", df.columns.tolist())

        results = []

        for idx, row in df.iterrows():
            # 跳过空行
            if pd.isna(row.iloc[0]) or row.iloc[0] == '':
                continue

            # 根据Excel结构提取字段
            # 假设列顺序为：时期, 三级, 建筑图, 图名, 建筑名称, 建筑类别, 建筑描述原文, 出处, 建成时间, 营造动因, 建筑历代名称, 建筑位置, 建筑范围/尺寸, 相关事件, 相关人物

            building_record = {
                'dynasty': str(row.iloc[0]).strip() if not pd.isna(row.iloc[0]) else None,  # 时期/朝代
                'building_name': str(row.iloc[3]).strip() if not pd.isna(row.iloc[3]) else None,  # 建筑名称
                'building_category': str(row.iloc[4]).strip() if not pd.isna(row.iloc[4]) else None,  # 建筑类别
                'description': str(row.iloc[5]).strip() if not pd.isna(row.iloc[5]) else None,  # 建筑描述原文
                'source': str(row.iloc[6]).strip() if not pd.isna(row.iloc[6]) else None,  # 出处
                'built_time': str(row.iloc[7]).strip() if not pd.isna(row.iloc[7]) else None,  # 建成时间
                'construction_motive': str(row.iloc[8]).strip() if not pd.isna(row.iloc[8]) else None,  # 营造动因
                'historical_names': str(row.iloc[9]).strip() if not pd.isna(row.iloc[9]) else None,  # 建筑历代名称
                'location': str(row.iloc[10]).strip() if not pd.isna(row.iloc[10]) else None,  # 建筑位置
                'scale': str(row.iloc[11]).strip() if not pd.isna(row.iloc[11]) else None,  # 建筑范围/尺寸
                'related_events': str(row.iloc[12]).strip() if not pd.isna(row.iloc[12]) else None,  # 相关事件
                'related_persons': str(row.iloc[13]).strip() if not pd.isna(row.iloc[13]) else None,  # 相关人物
            }

            # 从描述文本中提取结构化信息
            if building_record['description']:
                extracted_info = extract_building_info_from_text(building_record['description'])
                building_record.update(extracted_info)

            # 只添加有建筑名称的记录
            if building_record['building_name'] and building_record['building_name'] != 'nan':
                results.append(building_record)

        return results

    except Exception as e:
        print(f"读取文件时出错: {e}")
        import traceback
        traceback.print_exc()
        return []


def main():
    # 输入文件路径 - 修改为您的建筑数据文件路径
    input_file = './data/09重点建筑 - 总数据和各朝代数据.xlsx'

    # 输出文件路径
    output_file = 'outputs/important_building_data.json'

    print("开始提取建筑数据...")

    # 提取建筑数据
    data = extract_architectural_data_from_excel(input_file, sheet_name='总重点建筑')

    print(f"从建筑数据文件提取了 {len(data)} 条记录")

    # 保存为JSON文件
    Path(output_file).parent.mkdir(parents=True, exist_ok=True)
    with open(output_file, 'w', encoding='utf-8') as f:
        json.dump(data, f, ensure_ascii=False, indent=2)

    print(f"建筑数据已保存到: {output_file}")

    # 显示统计信息
    dynasties = set([record['dynasty'] for record in data if record['dynasty']])
    categories = set([record['building_category'] for record in data if record['building_category']])

    print(f"\n统计信息:")
    print(f"  涉及朝代: {len(dynasties)} 个")
    print(f"  建筑类别: {len(categories)} 种")
    print(f"  包含年代信息的建筑: {len([r for r in data if 'built_year' in r])} 个")
    print(f"  包含尺寸信息的建筑: {len([r for r in data if any(k in r for k in ['height_m', 'length_m', 'area_sqkm'])])} 个")

    # 显示前几条数据作为示例
    print("\n前3条数据示例:")
    for i, record in enumerate(data[:3], 1):
        print(f"\n记录 {i}:")
        print(f"  朝代: {record['dynasty']}")
        print(f"  建筑名称: {record['building_name']}")
        print(f"  建筑类别: {record['building_category']}")
        if 'built_year' in record:
            print(f"  建造年份: {record['built_year']}")
        if 'inferred_types' in record:
            print(f"  推断类型: {', '.join(record['inferred_types'])}")
        if 'location' in record and record['location']:
            print(f"  位置: {record['location']}")
    return data


if __name__ == '__main__':
    main()